package org.joy.db2;

import java.io.Closeable;
import java.io.IOException;

import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseConfig;
import com.sleepycat.db.DatabaseEntry;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.DatabaseType;
import com.sleepycat.db.Environment;
import com.sleepycat.db.LockMode;
import com.sleepycat.db.OperationStatus;

/**
 * DB class represents a abstract layer for Berkeley DB database. all the
 * disk-based data for this search engine will be stored in a "DB".
 * 
 * In our program, DB will be used for storing index, document and tf/Idf
 * information in the search engine
 * 
 * @author Song Liu (lamfeeling2@gmail.com)
 * 
 */
public class DB implements Closeable {

    private Database db;

    public DB() {
    }

    /**
     * open a DB using a Environment. This method should not be used directly.
     * 
     * @param env
     *            Berkeley DB Enviroment for this Database
     * @throws IOException
     */
    void open(Environment env) throws IOException {
	DatabaseConfig conf = new DatabaseConfig();
	conf.setAllowCreate(true);
	conf.setType(DatabaseType.BTREE);
	// conf.setBtreeComparator(new IndexEntry.Comparator());
	try {
	    this.db = env.openDatabase(null, this.getClass().toString(), null,
		    conf);
	} catch (Exception e) {
	    throw new IOException(e);
	}

    }

    /**
     * put an Entry to this Database
     * 
     * @param e
     *            Entry you want to put in
     * @throws IOException
     */
    public void putEntry(Entry e) throws IOException {
	put(e.getKeyEntry(), e.getValEntry());
    }

    public void put(DatabaseEntry key, DatabaseEntry val) throws IOException {
	try {
	    db.put(null, key, val);
	} catch (DatabaseException e) {
	    throw new IOException(e);
	}
    }

    /**
     * get an DatabaseEntry from DB
     * 
     * @param key
     *            key in DatabaseEntry format
     * @return
     * @throws IOException
     */
    public DatabaseEntry get(DatabaseEntry key) throws IOException {
	DatabaseEntry val = new DatabaseEntry();
	try {
	    OperationStatus s = db.get(null, key, val, LockMode.DEFAULT);
	} catch (DatabaseException e) {
	    e.printStackTrace();
	    throw new IOException(e);
	}
	return val;
    }

    /**
     * open a cursor for visiting all the entries in DB
     * 
     * @return DBCursor
     * @throws IOException
     */
    public DBCursor openCursor() throws IOException {
	try {
	    return new DBCursor(db.openCursor(null, null));
	} catch (DatabaseException e) {
	    throw new IOException();
	}
    }

    @Override
    public void close() throws IOException {
	try {
	    db.close();
	} catch (DatabaseException e) {
	    e.printStackTrace();
	    throw new IOException(e);
	}
    }
}
